package com.midian.common.utils;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;

import javax.annotation.Resource;
import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.midian.common.exception.BizException;
import com.midian.common.system.SysStatic;
import com.midian.model.pic.Pic;
import com.midian.service.pic.IPicService;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 图片操作帮助类
 * @author 飞
 *
 */
@Component("picUtils")
public class PicUtils {
	/**日志对象*/
	private static final Logger LOG = LoggerFactory.getLogger(PicUtils.class);
	/**图片业务*/
	private IPicService picService;
	
	@Resource(name="picService")
	public void setPicService(IPicService picService) {
		this.picService = picService;
	}
	

	/**
	 * 根据文件类型获取文件流
	 * @param fileObj 文件对象
	 * @return
	 * @throws IOException
	 */
	private InputStream getInputStream(Object fileObj) throws IOException {
		InputStream in = null;
		if(fileObj instanceof File) {
			in = new FileInputStream((File) fileObj);
		} else {
			in = ((MultipartFile) fileObj).getInputStream();
		}
		return in;
	}
	
	/**
	 * 上传图片，生成图片记录
	 * @param is 文件输入流
	 * @param fileName 文件名称
	 * @param isThumbnails 是否生成缩略图
	 * @return
	 */
	private String createPic(Object fileObj, String fileName) throws BizException {
		// 上传的图片列表
		FUtil fUtil = new FUtil();
		String picId = "";
		try {
//			picName = fUtil.generateFileName(FUtil.BUCKET_PIC);
			String picSuffix = StringUtil.getFileSuffix(fileName).toLowerCase();
			Pic pic = new Pic();
			pic.setSuffix(picSuffix);
			picService.add(pic);
			picId = pic.getId();
			//用表id作为图片文件名
			fUtil.uploadFile(FUtil.BUCKET_PIC, picId, picSuffix, getInputStream(fileObj));
			return picId;
		} catch (Exception e) {
			LOG.error("[PicUtils/uploadPic]" + e.getMessage());
			// 删除图片，抛出异常
			if(picId!=null&&!"".equals(picId)){
				picService.delete(picId);
				fUtil.deleteFile(picId);
			}
			throw new BizException(e.getMessage());
		}
	}
	
	
	/**
	 * 上传一张图片（SpringMVC上传的文件）
	 * @param file 图片文件
	 * @param isThumbnails 是否生成缩略图
	 * @return
	 * @throws Exception
	 */
	public String uploadPic(File file,String fileName) throws BizException {
		String picId = null;
		try {
			picId = createPic(file, fileName);
		} catch (BizException e) {
			LOG.error(e.getMessage());
		}
		return picId;
	}
	

	/**
	 * 上传一张图片（远程资源）
	 * @param url
	 * @param isThumbnails
	 * @return
	 */
	public String uploadPicByUrl(String url) {
		String picId = null;
		File dir = new File(SysStatic.TEMP_FILE_PATH);
		if(!dir.exists() || !dir.isDirectory()) {
			dir.mkdirs();
		}
		File tempFile = new File(SysStatic.TEMP_FILE_PATH, System.currentTimeMillis() + ".jpg");
		try {
			//下载url为本地临时文件
			FileUtils.copyURLToFile(new URL(url), tempFile);
			picId = createPic(tempFile, tempFile.getName());
		} catch (Exception e) {
			LOG.error(e.getMessage());
		} finally {
			tempFile.delete(); //删除本地文件
		}
		return picId;
	}
	
	/**
	 * 删除图片
	 * @param picId
	 */
	public void deletePic(String picId){
		try {
			FUtil fUtil = new FUtil();
			// 删除原图
			Pic pic = picService.get(picId);
			if (pic != null) {// 如果不为空删除旧图片
				fUtil.deleteFile(pic.getId());
			}
			picService.delete(picId);
			
			
		} catch (BizException e) {
			LOG.error("[PicUtils/deletePic]" + e.getMessage());
		}
	}
	/**
	 * 把图片集前4张合成一张正方形的图片
	 * @param files
	 * @return
	 * @throws BizException
	 */
	public String assemblePic(MultipartFile[] files) throws BizException{
		String picId = "";
		try {
			int width = 400;//宽
			int height = 400;//长
			BufferedImage tag = new BufferedImage(width*2+20, height*2+20,BufferedImage.TYPE_INT_RGB);
			Graphics g = tag.createGraphics();
			g.fillRect(0, 0, width*2+20, height*2+20);
			g.setClip(0, 0, width*2+20, height*2+20);
			int index=1;
			for (int i = 0; i < files.length; i++) {
				MultipartFile multipartFile = files[i];
				//前4张图片合并生成一张浏览图
				InputStream yin = multipartFile.getInputStream();
				InputStream srcin = null;
				String picSuffix = StringUtil.getFileSuffix(multipartFile.getOriginalFilename()).toLowerCase();
				if (files.length == 1) {
					Map<String,Object> retMap=ImageUtils.cut(yin, "1", picSuffix);
					srcin=new ByteArrayInputStream((byte[])retMap.get("b"));
					Image src = ImageIO.read(srcin);//构造Image对象
					g.drawImage(src, 0, 0, width*2+20, height*2+20, null);
					g.dispose();
					//创建相册合成图
					picId=createMixPic(tag);
				} else if(files.length == 2){
					Map<String,Object> retMap=ImageUtils.cut(yin, "2", picSuffix);
					srcin=new ByteArrayInputStream((byte[])retMap.get("b"));
					if (index == 1) {
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, 0, 0, width, height*2+20, null);
					} else if (index == 2) {
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, width+20, 0, width, height*2+20, null);
						g.dispose();
						//创建相册合成图
						picId=createMixPic(tag);
					}
				} else if(files.length == 3){
					if(index == 1){
						Map<String,Object> retMap=ImageUtils.cut(yin, "2", picSuffix);
						srcin=new ByteArrayInputStream((byte[])retMap.get("b"));
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, 0, 0, width, height*2+20, null);
					} else if(index == 2){
						Map<String,Object> retMap=ImageUtils.cut(yin, "1", picSuffix);
						srcin=new ByteArrayInputStream((byte[])retMap.get("b"));
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, width+20, 0, width, height, null);
					} else if(index == 3){
						Map<String,Object> retMap=ImageUtils.cut(yin, "1", picSuffix);
						srcin=new ByteArrayInputStream((byte[])retMap.get("b"));
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, width+20, height+20, width, height, null);
						g.dispose();
						//创建相册合成图
						picId=createMixPic(tag);
					}
				} else if (files.length >= 4) {
					Map<String,Object> retMap=ImageUtils.cut(yin, "1", picSuffix);
					srcin=new ByteArrayInputStream((byte[])retMap.get("b"));
					if(index == 1){
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, 0, 0, width, height, null);
					} else if(index == 2){
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, width+20, 0, width, height, null);
					} else if(index == 3){
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, 0, height+20, width, height, null);
					} else if(index == 4){
						Image src = ImageIO.read(srcin);//构造Image对象
						g.drawImage(src, width+20, height+20, width, height, null);
						g.dispose();
						//创建相册合成图
						picId=createMixPic(tag);
						break;
					}
				}
			}
			return picId;
		} catch (IOException e) {
			LOG.error(e.toString());
			throw new BizException(e.getMessage());
		}
	}
	/**
	 * 把合成的图片上传到服务
	 * @param tag
	 * @return
	 * @throws BizException
	 */
	private String createMixPic(BufferedImage tag) throws BizException {
		FUtil fUtil=new FUtil();
		String picId="";
		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream(); // 输出到文件流
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(tag);// 近JPEG编码
			byte[] ba = out.toByteArray();
			ByteArrayInputStream bin = new ByteArrayInputStream(ba);
			// 上传前4张合并的图片
			String picSuffix = ".jpg";
//			mixPicName=fUtil.generateFileName(FUtil.BUCKET_PIC);
			Pic pic = new Pic();
			pic.setSuffix(picSuffix);
			picService.add(pic);
			picId = pic.getId();
			fUtil.uploadFile(FUtil.BUCKET_PIC, pic.getId(), picSuffix, bin);
			bin.close();
			out.close();
			return pic.getId();
		} catch (Exception e) {
			LOG.error(e.toString());
			if(StringUtils.isNotBlank(picId)){
			picService.delete(picId);
			fUtil.deleteFile(picId);
			}
			throw new BizException(e.getMessage());
		} 
	}
}
